home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
17 Bit Software 6: Level 6
/
17 Bit - Level 6 (1998)(Epic Marketing)[!].iso
/
!applications!
/
quadra_comp.v2.03
/
qcfastreplay.s
next >
Wrap
Text File
|
1996-09-07
|
7KB
|
335 lines
* This replayroutine was written by Bo Lincoln (Eternal).
* Copyright © 1993 Technological Artwork. All rights reserved.
* You may use this routine in your programs.
* This is the fast-routine, i.e it uses level 6 interrupt to wait for
* the dma. Worst case is about 8 rasterlines (tested with an average module).
* How to use: Call QC_init to init the mod.
* Call QC_music every vertical blank.
* Call QC_end to stop.
* The EMOD should be at QC_data.
* You can not use Tempo in this routine. (Then you have to put the whole
* routine in the level 6 interrupt).
QC_dmawait = 255
cia_CRA = $e00
cia_ICR = $d00
cia_TALO = $400
cia_TAHI = $500
section QC,code_c
s: move.w $dff01c,-(sp)
move.w #$7fff,$dff09a ;Turn off all interrupts
bsr QC_init
loop: bsr QC_music
loop2: cmp.b #70,$dff006
bne loop2
loop3: cmp.b #70,$dff006
beq loop3
btst #6,$bfe001
bne loop
bsr QC_end
move.w (sp)+,d0
or.w #$8000,d0
move.w d0,$dff09a
rts
QC_init:lea QC_data(pc),a0 ;Check if the module is ok
cmp.l #"FORM",(a0)
bne QC_initerr
cmp.l #"EMOD",8(a0)
bne QC_initerr
cmp.l #"EMIC",12(a0)
bne QC_initerr
cmp.w #1,20(a0)
bne QC_initerr
or.b #$2,$bfe001
moveq #0,d7 ;Get the adresses to the sampleinfos
move.b 63(a0),d7 ;and init the real adresses in the infos
subq #1,d7
lea 64(a0),a0
lea QC_samplepointers(pc),a1
QC_sploop:moveq #0,d0
move.b (a0),d0
add.w d0,d0
add.w d0,d0
move.l a0,(a1,d0.w)
add.l #QC_data,30(a0)
move.l 30(a0),a2
clr.w (a2)
lea 34(a0),a0
dbf d7,QC_sploop
lea QC_patternpointers(pc),a1 ;Get the patternadresses
moveq #0,d7
addq #1,a0
move.b (a0)+,d7
subq #1,d7
QC_pploop:moveq #0,d0
move.b (a0),d0
add.w d0,d0
add.w d0,d0
move.l a0,(a1,d0.w)
add.l #QC_data,22(a0)
lea 26(a0),a0
dbf d7,QC_pploop
move.l $78,QC_oldIrq
clr.w QC_nrofpos
move.b (a0)+,QC_nrofpos+1
move.l a0,QC_posstart
moveq #0,d0
move.b (a0),d0
add.w d0,d0
add.w d0,d0
move.l (a1,d0.w),a1
move.l 22(a1),QC_currpattpointer
move.b 1(a1),QC_breakrow+1
move.w #6,QC_speed
move.w QC_speed(pc),QC_speedcount
clr.b QC_newposflag
clr.w QC_rowcount
clr.w QC_pos
move.w #1,t_length+QC_chan1
move.w #1,t_length+QC_chan2
move.w #1,t_length+QC_chan3
move.w #1,t_length+QC_chan4
move.w #1,t_replen+QC_chan1
move.w #1,t_replen+QC_chan2
move.w #1,t_replen+QC_chan3
move.w #1,t_replen+QC_chan4
moveq #0,d0
QC_end: move.b #$7f,$bfd000+cia_ICR
move.w #$2000,$dff09a
move.w #$2000,$dff09c
move.l QC_oldirq,$78
move.w #$f,$dff096
clr.w $dff0a8
clr.w $dff0b8
clr.w $dff0c8
clr.w $dff0d8
rts
QC_initerr:moveq #-1,d0
rts
QC_music:
addq.w #1,QC_speedcount
move.w QC_speed,d0
cmp.w QC_speedcount,d0
bgt QC_nonew
tst.b QC_pattwait
beq QC_getnotes
subq.b #1,QC_pattwait
clr.w QC_speedcount
QC_nonew:lea QC_samplepointers(pc),a4
lea QC_periodtable(pc),a3
lea QC_chan1(pc),a6
lea $dff0a0,a5
bsr QC_chkplayfx
lea QC_chan2-QC_chan1(a6),a6
lea $10(a5),a5
bsr QC_chkplayfx
lea QC_chan2-QC_chan1(a6),a6
lea $10(a5),a5
bsr QC_chkplayfx
lea QC_chan2-QC_chan1(a6),a6
lea $10(a5),a5
bsr QC_chkplayfx
move.w QC_dmacon(pc),$dff096
beq QC_mend
lea $bfd000,a0
move.b #$7f,cia_ICR(a0)
move.w #$2000,$dff09c
move.l #QC_setdma,$78.w
move.w #$e000,$dff09a
clr.b cia_CRA(a0)
move.b #QC_dmawait,cia_TALO(a0)
clr.b cia_TAHI(a0)
move.b #$11,cia_CRA(a0)
move.b #$81,cia_ICR(a0)
rts
QC_chkplayfx:
lea QC_playfx(pc),a2
move.b t_cmd(a6),d0
and.w #$f,d0
add.w d0,d0
add.w d0,d0
move.l (a2,d0.w),a0
jmp (a0)
QC_getnotes:
clr.w QC_speedcount
move.l QC_currpattpointer(pc),a0
move.w QC_rowcount(pc),d0
asl.w #4,d0
add.w d0,a0
lea QC_samplepointers(pc),a4
lea QC_periods(pc),a3
lea $dff0a0,a5
lea QC_chan1(pc),a6
bsr QC_playnote
lea $10(a5),a5
lea QC_chan2-QC_chan1(a6),a6
bsr QC_playnote
lea $10(a5),a5
lea QC_chan2-QC_chan1(a6),a6
bsr QC_playnote
lea $10(a5),a5
lea QC_chan2-QC_chan1(a6),a6
bsr QC_playnote
move.w QC_dmacon(pc),$dff096
beq QC_update
lea $bfd000,a0
move.b #$7f,cia_ICR(a0)
move.w #$2000,$dff09c
move.w #$e000,$dff09a
move.l #QC_setdma,$78.w
clr.b cia_CRA(a0)
move.b #QC_dmawait,cia_TALO(a0)
clr.b cia_TAHI(a0)
move.b #$11,cia_CRA(a0)
move.b #$81,cia_ICR(a0)
QC_update:
QC_tstnewpos:tst.b QC_newposflag
beq QC_tstend
clr.b QC_newposflag
move.w QC_newposnr,QC_pos
bra QC_newpos
QC_tstend:tst.b QC_jumpbreakflag
beq QC_tstend2
clr.b QC_jumpbreakflag
move.w QC_looprow(pc),d0
cmp.w QC_breakrow(pc),d0
bgt QC_mend
move.w d0,QC_rowcount
rts
QC_tstend2:
addq.w #1,QC_rowcount
move.w QC_rowcount(pc),d0
cmp.w QC_breakrow(pc),d0
ble QC_mend
addq.w #1,QC_pos
QC_newpos:move.w QC_pos(pc),d0
cmp.w QC_nrofpos(pc),d0
blt QC_getpos
clr.w QC_pos
moveq #0,d0
QC_getpos:move.l QC_posstart(pc),a0
move.b (a0,d0.w),d0
add.w d0,d0
add.w d0,d0
lea QC_patternpointers(pc),a0
move.l (a0,d0.w),a0
move.l 22(a0),QC_currpattpointer
move.b 1(a0),QC_breakrow+1
move.w QC_newrow(pc),QC_rowcount
clr.w QC_newrow
QC_mend:rts
QC_setDMA:
tst.b $bfd000+cia_ICR
or.w #$8000,QC_dmacon
move.w QC_dmacon(pc),$dff096
clr.w QC_dmacon
move.l #QC_fixloop,$78.w
move.w #$2000,$dff09c
rte
QC_fixloop:
tst.b $bfd000+cia_ICR
move.l a5,-(sp)
move.l a0,-(sp)
lea $dff000,a5
lea QC_chan1+t_repeat(pc),a0
move.l (a0),$a0(a5)
move.w 4(a0),$a4(a5)
move.l QC_chan2-QC_chan1(a0),$b0(a5)
move.w 4+QC_chan2-QC_chan1(a0),$b4(a5)
move.l QC_chan3-QC_chan1(a0),$c0(a5)
move.w 4+QC_chan3-QC_chan1(a0),$c4(a5)
move.l QC_chan4-QC_chan1(a0),$d0(a5)
move.w 4+QC_chan4-QC_chan1(a0),$d4(a5)
clr.b $bfd000+cia_CRA
move.b #$7f,$bfd000+cia_ICR
move.w #$2000,$dff09a
move.w #$2000,$dff09c
move.l (sp)+,a0
move.l (sp)+,a5
rte
QC_playnote:move.l (a0)+,(a6)
moveq #0,d0
move.b (a6),d0
beq QC_isnote
add.w d0,d0
add.w d0,d0
move.l (a4,d0.w),a1
move.b 1(a1),t_volume+1(a6)
move.b 25(a1),d0
and.w #$f,d0
add.w d0,d0
add.w d0,d0
move.l (a3,d0.w),t_finetune(a6)
move.l 30(a1),d1
move.l d1,t_start(a6)
move.w t_volume(a6),8(a5)
btst #0,24(a1)
beq QC_noloop
moveq #0,d0
move.w 26(a1),d0
add.l d0,d1
add.l d0,d1
move.l d1,t_repeat(a6)
moveq #0,d0
move.w 26(a1),d0
moveq #0,d1
move.w 28(a1),d1
add.l d0,d1
move.w d1,t_length(a6)
move.w 28(a1),t_replen(a6)
bra QC_isnote
QC_noloop:clr.l t_repeat(a6)
move.w #$1,t_replen(a6)
move.w 2(a1),t_length(a6)
QC_isnote:
tst.b t_notenr(a6)
blt QC_chkfirstfx
move.b t_notenr(a6),t_notenr2+1(a6)
move.w t_cmd(a6),d0
and.w #$ff0,d0
cmp.w #$e50,d0
beq QC_setfinetunefirst
and.w #$f00,d0
cmp.w #$300,d0
beq QC_settoneport
cmp.w #$500,d0
beq QC_settoneport
QC_getper:move.w t_notenr2(a6),d0
add.w d0,d0
move.l t_finetune(a6),a2
move.w (a2,d0.w),t_period(a6)
move.w t_cmd(a6),d0
and.w #$ff0,d0
cmp.w #$ed0,d0
beq QC_notedelay
move.w t_dmabit(a6),d0
or.w d0,QC_dmacon
move.l t_start(a6),(a5)
move.w t_length(a6),4(a5)
move.w t_period(a6),6(a5)
QC_chkfirstfx:
lea QC_fxaftersetperiod(pc),a2
moveq #0,d0
move.b t_cmd(a6),d0
add.w d0,d0
add.w d0,